package com.mineoj.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mineoj.common.ErrorCode;
import com.mineoj.exception.BusinessException;
import com.mineoj.mapper.NewsCommentMapper;
import com.mineoj.model.dto.newscomment.NewsCommentAddRequest;
import com.mineoj.model.entity.NewsComment;
import com.mineoj.model.entity.News;
import com.mineoj.model.entity.NewsComment;
import com.mineoj.model.entity.User;
import com.mineoj.model.vo.NewsCommentVO;
import com.mineoj.service.NewsCommentService;
import com.mineoj.mapper.NewsCommentMapper;
import com.mineoj.service.NewsService;
import com.mineoj.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author 明月
* @description 针对表【news_comment(新鲜事评论)】的数据库操作Service实现
* @createDate 2025-04-11 19:39:33
*/
@Service
public class NewsCommentServiceImpl extends ServiceImpl<NewsCommentMapper, NewsComment>
    implements NewsCommentService{

    @Resource
    private NewsService newsService;

    @Resource
    private NewsCommentMapper newsCommentMapper;

    @Resource
    private UserService userService;

    /**
     * 添加评论
     * @param newsCommentAddRequest 评论信息
     * @param loginUser 登录用户
     * @return 评论id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long doNewsComment(NewsCommentAddRequest newsCommentAddRequest, User loginUser) {
        // 校验内容是否为空
        if (newsCommentAddRequest.getContent() == null || newsCommentAddRequest.getContent().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容不能为空");
        }

        long newsId = newsCommentAddRequest.getNewsId();
        // 判断实体是否存在
        News news = newsService.getById(newsId);
        if (news == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        // 构建评论对象
        NewsComment newsComment = new NewsComment();
        newsComment.setNewsId(newsId);
        newsComment.setContent(newsCommentAddRequest.getContent());
        newsComment.setUserId(loginUser.getId());

        boolean save = this.save(newsComment);
        if (!save) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据插入失败");
        }

        // 更新新鲜事评论数
        boolean updateSuccess = newsService.update()
                .eq("id", newsId)
                .setSql("commentNum = commentNum + 1")
                .update();
        if (!updateSuccess) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论数更新失败");
        }

        return newsComment.getId();
    }

    /**
     * 删除评论
     * @param id 评论ID
     * @param loginUser 登录用户
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteNewsComment(long id, User loginUser) {
        // 判断是否存在
        NewsComment oldNewsComment = this.getById(id);
        if (oldNewsComment == null ) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 仅本人或管理员可删除
        if (!oldNewsComment.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        if (this.removeById(id)) {
            // 更新新鲜事评论数
            boolean updateSuccess = newsService.update()
                    .eq("id", oldNewsComment.getNewsId())
                    .setSql("commentNum = commentNum - 1")
                    .update();
            if (!updateSuccess) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "评论数更新失败");
            }
            return true;
        }

        return false;
    }


    /**
     * 获取评论封装
     * @param newsComment 评论
     * @param loginUser 登录用户
     * @return 评论封装
     */
    @Override
    public NewsCommentVO getNewsCommentVO(NewsComment newsComment, User loginUser) {
        NewsCommentVO newsCommentVO = NewsCommentVO.objToVo(newsComment);
        return newsCommentVO;
    }

    /**
     * 获取评论分页封装，包含用户信息
     * @param newsCommentPage 分页对象
     * @param request
     * @return 分页对象
     */
    @Override
    public Page<NewsCommentVO> getNewsCommentVOPage(Page<NewsComment> newsCommentPage, HttpServletRequest request) {
        List<NewsComment> newsCommentList = newsCommentPage.getRecords();
        Page<NewsCommentVO> newsCommentVOPage = new Page<>(newsCommentPage.getCurrent(), newsCommentPage.getSize(), newsCommentPage.getTotal());
        if (CollectionUtils.isEmpty(newsCommentList)) {
            return newsCommentVOPage;
        }
        // 1. 关联查询用户信息
        Set<Long> userIdSet = newsCommentList.stream().map(NewsComment::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 填充信息
        List<NewsCommentVO> newsCommentVOList = newsCommentList.stream().map(newsComment -> {
            NewsCommentVO newsCommentVO = NewsCommentVO.objToVo(newsComment);
            Long userId = newsComment.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            newsCommentVO.setUserVO(userService.getUserVO(user));
            return newsCommentVO;
        }).collect(Collectors.toList());
        newsCommentVOPage.setRecords(newsCommentVOList);
        return newsCommentVOPage;
    }

}




